#include <pcrecpp.h>
#include <iostream>
#include <fstream>
#include <cstdlib>
#include "testrunner.h"

TestRunner::~TestRunner()
{
	std::vector<std::string>::iterator it;
	
	for (it = tmp_files.begin(); it != tmp_files.end(); ++it) {
		unlink(it->c_str());
	}
	if (dp) {
		closedir(dp);
	}
}

void TestRunner::show_result(void) const
{
	std::cout << "-----------------------------------" << std::endl;
	std::cout << "Tests: " << files.size() << std::endl;
	std::cout << "-----------------------------------" << std::endl;
	std::cout << "Passed tests: " << pass << std::endl;
	std::cout << "Failed tests: " << fail << std::endl;
	std::cout << "-----------------------------------" << std::endl;
}

void TestRunner::find(char* dir)
{
	struct dirent *dirp;
	
	if ((dp = opendir(dir)) == NULL) {
		std::cout << "Couldn't open the directory" << std::endl;
		exit(1);
	}

	dirname = dir;
	while ((dirp = readdir(dp)) != NULL) {
		if (strcmp(dirp->d_name, ".") == 0 ||
			strcmp(dirp->d_name, "..") == 0 ||
			strstr(dirp->d_name, ".tmp") ||
			strstr(dirp->d_name, ".svn")) {
			continue;
		}
		files.push_back(dirp->d_name);
	}
}

void TestRunner::run(void)
{
	FILE * fp;
	std::vector<char*>::iterator it;
	std::string file_name, tmp_file;
	pcrecpp::RE regex("((?s:.(?!--))+)\\s*--((?s:.(?!--))+)\\s*--\\s*((?s:.+))\\s+");
	
	for (it = files.begin(); it != files.end(); ++it) {
		char result[300] = {0};
		std::string title, source, expect;
			
		file_name = std::string(dirname) + *it;
		tmp_file = file_name + ".tmp";
		
		regex.FullMatch(read_file(file_name.c_str()), &title, &source, &expect);
		
		write_file(tmp_file, source);
		
		fp = popen((std::string("./todo -f ") + tmp_file).c_str(), "r");
		fread(result, 1, sizeof(result)-1, fp);
		fclose(fp);
		
		std::cout << title << ":" << file_name << " >> ";
		
		if (pcrecpp::RE(expect).FullMatch(result)) {
			std::cout << "OK!" << std::endl;
			pass++;
		} else {
			std::cout << "Failed!" << std::endl;
			std::cout << "Expected: '" << expect << "' got '" << result << "'" << std::endl;
			fail++;
		}
	}
}

void TestRunner::write_file(std::string& name, std::string& source)
{
	std::ofstream file(name.c_str());
	
	file << source;
	file.close();

	tmp_files.push_back(name);
}

std::string TestRunner::read_file(const char* name) const
{
	std::string source, line;
	std::ifstream file;
	
	file.open(name);
	
	if (!file) {
		std::cout << "Couldn't open file " << name << std::endl;
		exit(1);
	}
	
	while (!file.eof()) {
		getline(file, line);
		source += line + '\n';
	}
	file.close();

	return source;	
}
